#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/binary_info.h"
#include "hardware/spi.h"

#include "wizchip_conf.h"
#include "w6100.h"
#include "w6100_spi.h"
#include "dhcpv4.h"


void dhcp_test(void);
void my_ip_conflict(void);
void my_ip_assign(void);
void network_init(void);
bool repeating_timer_callback(struct repeating_timer *t);


wiz_NetInfo net_info = {
    .mac = {0x00, 0x08, 0xdc, 0x16, 0xed, 0x2e},
    .ip = {192, 168, 1, 10},
    .sn = {255, 255, 255, 0},
    .gw = {192, 168, 1, 1},
    .dns = {8, 8, 8, 8},
    .ipmode = NETINFO_DHCP_V4};
uint8_t my_dhcp_retry = 0;



int main()
{
    uint8_t temp;
    uint8_t databuf[2048];
    stdio_init_all();
    sleep_ms(2000);
    printf("W6100 network install example.\r\n");
    wizchip_initialize();
    /* Chip software reset. All registers are initialized. */
    wizchip_sw_reset();
    /* Determine the network lock register status. */
    if(!ctlwizchip(SYS_NET_LOCK, &temp))
    {   
        printf("unlock.\n");
        NETUNLOCK();
    }
    setSHAR(net_info.mac);
    DHCPv4_init(0,databuf);
    reg_dhcpv4_cbfunc(my_ip_assign,my_ip_assign,my_ip_conflict);
    while (true)
    {   
        dhcp_test();
        sleep_ms(100);
    }
}

void dhcp_test(void)
{
    switch (DHCPv4_run())
    {
    case DHCP_IPV4_ASSIGN:
    case DHCP_IPV4_CHANGED:
        break;
    case DHCP_IPV4_LEASED:
        break;
    case DHCPV4_FAILED:
        my_dhcp_retry++;
        if (my_dhcp_retry > 5)
        {
            printf(">>DHCP %d Failed\r\n", my_dhcp_retry);
            my_dhcp_retry = 0;
            DHCPv4_stop();
            network_init();
        }
    default:
        break;
    }
}


void my_ip_conflict(void)
{
    printf("CONFLICT IP from DHCP\r\n");
    while(1);
}


void my_ip_assign(void)
{
    getIPfromDHCPv4(net_info.ip);
    getGWfromDHCPv4(net_info.gw);
    getSNfromDHCPv4(net_info.sn);
    getDNSfromDHCPv4(net_info.dns);
    net_info.ipmode = NETINFO_DHCP_V4;
    network_init();
    printf("DHCP LEASED TIME:%ld Sec.\r\n",getDHCPv4Leasetime());
}

void network_init(void)
{
    uint8_t tmpstr[6] = {0,};
    wiz_NetInfo netinfo;
    ctlnetwork(CN_SET_NETINFO,(void*)&net_info);
    ctlnetwork(CN_GET_NETINFO,(void*)&netinfo);
    ctlwizchip(CW_GET_ID,(void*)tmpstr);

    if(netinfo.ipmode == NETINFO_DHCP_V4) printf("\r\n=== %s NET CONF:DHCP ===\r\n",(char*)tmpstr);
    else printf("\r\n===%s NET CONF : Static === \r\n",(char*)tmpstr);

    print_net_info(&net_info);
}

/* Timer */
bool repeating_timer_callback(struct repeating_timer *t)
{
    DHCPv4_time_handler();
    return true;
}